package com.easylinkin.linkappapi.lobar.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.easylinkin.linkappapi.common.model.RequestModel;
import com.easylinkin.linkappapi.common.service.CommonService;
import com.easylinkin.linkappapi.device.entity.Device;
import com.easylinkin.linkappapi.device.mapper.DeviceMapper;
import com.easylinkin.linkappapi.lobar.dto.*;
import com.easylinkin.linkappapi.lobar.entity.*;
import com.easylinkin.linkappapi.lobar.entity.emp.EmpUserBase;
import com.easylinkin.linkappapi.lobar.mapper.*;
import com.easylinkin.linkappapi.lobar.service.UserProjectService;
import com.easylinkin.linkappapi.lobar.service.WarningNotifierService;
import com.easylinkin.linkappapi.lobar.service.WarningService;
import com.easylinkin.linkappapi.lobar.vo.*;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;

import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Resource;

import com.easylinkin.linkappapi.security.entity.LinkappUser;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import site.morn.rest.RestBuilders;
import site.morn.rest.RestMessage;

/**
 * <p>
 * 预警
 * </p>
 *
 * @author kanyuanfeng
 * @since 2022-05-24
 */
@Service
public class WarningServiceImpl implements WarningService {

  @Resource
  private LinkappUserContextProducer linkappUserContextProducer;

  @Autowired
  private UserWarningMapper userWarningMapper;

  @Autowired
  private GroupWarningMapper groupWarningMapper;

  @Autowired
  private AgeWarningMapper ageWarningMapper;

  @Autowired
  private CertificateWarningMapper certificateWarningMapper;

  @Autowired
  private WarningConfigMapper warningConfigMapper;

  @Autowired
  private LaborCompanyProjectMapper laborCompanyProjectMapper;

  @Autowired
  private WarningMapper warningMapper;

  @Autowired
  private EpidemicWarningMapper epidemicWarningMapper;

  @Resource
  private CommonService commonService;

  @Autowired
  private GateMapper gateMapper;

  @Autowired
  private EmpUserBaseMapper empUserBaseMapper;

  @Autowired
  private DeviceMapper deviceMapper;

  @Autowired
  private UserProjectService userProjectService;

  @Resource
  private UserProjectMapper userProjectMapper;

  @Resource
  private UserCertificateMapper userCertificateMapper;

  @Resource
  private UserOutinWarningMapper userOutinWarningMapper;

  @Resource
  private UserClockMapper userClockMapper;

  /**
   * @Description: 根据条件，分页(不分页)查询人员出勤预警
   * @author kan yuanfeng
   * @date 2020/11/04 11:42
   */
  @Override
  public IPage<UserWarningDTO> queryUserWarning(RequestModel<UserWarningDTO> requestModel) {
    Page page = requestModel.getPage();
    UserWarningDTO userWarningDTO = requestModel.getCustomQueryParams();
    //项目id 过滤
    userWarningDTO.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
    Page page1 = new Page();
    page1.setSize(100000);
    LaborCompanyProjectDTO laborCompanyProjectDTO = new LaborCompanyProjectDTO();
    laborCompanyProjectDTO.setTenantId(userWarningDTO.getTenantId());
    IPage<LaborCompanyProjectDTO> laborCompanyProjectDTOIPage = laborCompanyProjectMapper
        .queryListByPage(page1, laborCompanyProjectDTO);
    //结束时间
    if (null != userWarningDTO.getEndTime()){
      userWarningDTO.setEndTime(DateUtil.endOfDay(userWarningDTO.getEndTime()));
    }
    IPage<UserWarningDTO> userWarningDTOIPage = userWarningMapper.queryList(page,userWarningDTO);
    userWarningDTOIPage.getRecords().forEach(r ->{
      //设置参建单位
      List<LaborCompanyProjectDTO> dtos = laborCompanyProjectDTOIPage.getRecords().stream()
          .filter(re -> Objects.equals(r.getCompanyProjectId(),re.getCompanyProjectId()))
          .collect(Collectors.toList());
      if (dtos.size() > 0){
        r.setCompanyName(dtos.get(0).getName());
      }
    });
    return userWarningDTOIPage;
  }

  /**
   * @Description: 根据条件，分页(不分页)查询疫情监测预警
   * @author xy
   * @date 2022/08/16 15:55
   */
  @Override
  public IPage<EpidemicWarningDTO> queryEpidemicWarning(RequestModel<EpidemicWarningDTO> requestModel) {
    Page page = requestModel.getPage();
    EpidemicWarningDTO epidemicWarningDTO = requestModel.getCustomQueryParams();
    //项目id 过滤
    epidemicWarningDTO.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
    Page page1 = new Page();
    page1.setSize(100000);
    LaborCompanyProjectDTO laborCompanyProjectDTO = new LaborCompanyProjectDTO();
    laborCompanyProjectDTO.setTenantId(epidemicWarningDTO.getTenantId());
    IPage<LaborCompanyProjectDTO> laborCompanyProjectDTOIPage = laborCompanyProjectMapper
        .queryListByPage(page1, laborCompanyProjectDTO);
    //结束时间
    if (null != epidemicWarningDTO.getEndTime()){
      epidemicWarningDTO.setEndTime(DateUtil.endOfDay(epidemicWarningDTO.getEndTime()));
    }
    IPage<EpidemicWarningDTO> epidemicWarningDTOIPage = epidemicWarningMapper.queryList(page,epidemicWarningDTO);
    epidemicWarningDTOIPage.getRecords().forEach(r ->{
      //设置参建单位
      List<LaborCompanyProjectDTO> dtos = laborCompanyProjectDTOIPage.getRecords().stream()
          .filter(re -> Objects.equals(r.getCompanyProjectId(),re.getCompanyProjectId()))
          .collect(Collectors.toList());
      if (dtos.size() > 0){
        r.setCompanyName(dtos.get(0).getName());
      }
    });
    return epidemicWarningDTOIPage;
  }

  /**
   * @Description: 根据条件，分页(不分页)查询班组出勤预警
   * @author kan yuanfeng
   * @date 2020/11/04 11:42
   */
  @Override
  public IPage<GroupWarningDTO> queryGroupWarning(RequestModel<GroupWarningDTO> requestModel) {
    Page page = requestModel.getPage();
    GroupWarningDTO groupWarningDTO = requestModel.getCustomQueryParams();
    //项目id 过滤
    groupWarningDTO.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
    //结束时间
    if (null != groupWarningDTO.getEndTime()){
      groupWarningDTO.setEndTime(DateUtil.endOfDay(groupWarningDTO.getEndTime()));
    }
    IPage<GroupWarningDTO> groupWarningDTOIPage = groupWarningMapper.queryList(page,groupWarningDTO);
    return groupWarningDTOIPage;
  }

  /**
   * @Description: 根据条件，分页(不分页)查询年龄预警
   * @author kan yuanfeng
   * @date 2020/11/04 11:42
   */
  @Override
  public IPage<AgeWarningDTO> queryAgeWarning(RequestModel<AgeWarningDTO> requestModel) {
    Page page = requestModel.getPage();
    AgeWarningDTO ageWarningDTO = requestModel.getCustomQueryParams();
    //项目id 过滤
    ageWarningDTO.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
    Page page1 = new Page();
    page1.setSize(100000);
    LaborCompanyProjectDTO laborCompanyProjectDTO = new LaborCompanyProjectDTO();
    laborCompanyProjectDTO.setTenantId(ageWarningDTO.getTenantId());
    IPage<LaborCompanyProjectDTO> laborCompanyProjectDTOIPage = laborCompanyProjectMapper
        .queryListByPage(page1, laborCompanyProjectDTO);
    //结束时间
    if (null != ageWarningDTO.getEndTime()){
      ageWarningDTO.setEndTime(DateUtil.endOfDay(ageWarningDTO.getEndTime()));
    }
    IPage<AgeWarningDTO> ageWarningDTOIPage = ageWarningMapper.queryList(page,ageWarningDTO);
    ageWarningDTOIPage.getRecords().forEach(r ->{
      //设置参建单位
      List<LaborCompanyProjectDTO> dtos = laborCompanyProjectDTOIPage.getRecords().stream()
          .filter(re -> re.getCompanyProjectId().equals(r.getCompanyProjectId()))
          .collect(Collectors.toList());
      if (dtos.size() > 0){
        r.setCompanyName(dtos.get(0).getName());
      }
    });
    return ageWarningDTOIPage;
  }

  /**
   * @Description: 根据条件，分页(不分页)查询证书预警
   * @author kan yuanfeng
   * @date 2020/11/04 11:42
   */
  @Override
  public IPage<CertificateWarningDTO> queryCertificateWarning(
      RequestModel<CertificateWarningDTO> requestModel) {
    Page page = requestModel.getPage();
    CertificateWarningDTO warningDTO = requestModel.getCustomQueryParams();
    //项目id 过滤
    warningDTO.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
    IPage<CertificateWarningDTO> certificateWarningDTOIPage = certificateWarningMapper.queryList(page,warningDTO);
    return certificateWarningDTOIPage;
  }

  /**
   * @Description: 查询预警设置(没有设置的查询默认设置)
   * @author kan yuanfeng
   * @date 2020/11/04 11:42
   */
  @Override
  public WarningConfigDTO queryWarningConfig(Boolean isDefault) {
    String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
    QueryWrapper<WarningConfig> queryWrapper1 = new QueryWrapper<>();
    queryWrapper1.eq("tenant_id_",tenantId);
    List<WarningConfig> configs = warningConfigMapper.selectList(queryWrapper1);
    if (Boolean.TRUE.equals(isDefault) || null == configs || configs.size() < 1){
      //查询默认的
      QueryWrapper<WarningConfig> queryWrapper2 = new QueryWrapper<>();
      queryWrapper2.isNull("tenant_id_");
      configs = warningConfigMapper.selectList(queryWrapper2);
    }
    WarningConfigDTO warningConfigDTO = new WarningConfigDTO();
    BeanUtils.copyProperties(configs.get(0),warningConfigDTO);
    List<WarningNotifier> notifierList = warningNotifierService
        .findAllNotifiersByTenantId(tenantId);
    if(CollectionUtil.isNotEmpty(notifierList)&&Boolean.FALSE.equals(isDefault)){
      List<Integer> warningTypes = notifierList.stream().map(WarningNotifier::getWarningType).collect(Collectors.toList());
      List<String> userIds = Arrays.asList(notifierList.get(0).getWarningNotifiers().split(","));
      Integer noticeSwitch = notifierList.get(0).getNoticeSwitch();
      warningConfigDTO.setWarningTypes(warningTypes);
      warningConfigDTO.setWarningNotifiers(userIds);
      warningConfigDTO.setNoticeSwitch(noticeSwitch);
    }
    return warningConfigDTO;
  }

  @Resource
  private WarningNotifierService warningNotifierService;

  /**
   * @Description: 设置预警参数
   * @author kan yuanfeng
   * @date 2020/11/04 11:42
   */
  @Override
  public void updateWarningConfig(WarningConfigDTO warningConfig) {
    String tenantId = warningConfig.getTenantId() != null ? warningConfig.getTenantId()
        : linkappUserContextProducer.getNotNullCurrent().getTenantId();
    QueryWrapper<WarningConfig> queryWrapper1 = new QueryWrapper<>();
    queryWrapper1.eq("tenant_id_",tenantId);
    List<WarningConfig> configs = warningConfigMapper.selectList(queryWrapper1);
    if (null != configs && configs.size() > 0){
      UpdateWrapper<WarningConfig> updateWrapper = new UpdateWrapper<>();
      updateWrapper.eq("tenant_id_",tenantId);
      warningConfig.setModifyTime(new Date());
      warningConfigMapper.update(warningConfig,updateWrapper);
    }else {
      warningConfig.setTenantId(tenantId);
      warningConfig.setModifyTime(new Date());
      warningConfig.setCreateTime(new Date());
      warningConfig.setId(null);
      warningConfigMapper.insert(warningConfig);
    }
    // 新增或更新告警推送配置
    warningNotifierService
        .addOrUpdateWarningNotifier(warningConfig.getWarningTypes(), warningConfig.getWarningNotifiers(),
            warningConfig.getNoticeSwitch(), tenantId);
  }

  @Override
  public IPage<Warning> queryWarning(RequestModel<WarningDTO> requestModel) {
    Page page = requestModel.getPage();
    //项目id 过滤
    WarningDTO customQueryParams = requestModel.getCustomQueryParams();
    customQueryParams.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
//    customQueryParams.setUserType(linkappUserContextProducer.getCurrent().getType());
    IPage<Warning> warningPage = warningMapper.queryList(page,customQueryParams);
    //特殊处理
    List<Warning> warningList = warningPage.getRecords();
    if (CollectionUtil.isNotEmpty(warningList)){
      warningList.stream().forEach(t->{
        Integer warningType = t.getWarningType();
        if (warningType != null){
          switch (warningType) {
            case 5:
              //查询人员出场异常告警对应的最后一次打卡记录
              UserClock inClock = userClockMapper.getOutinWarnClockIn(t.getId());
              t.setInClock(inClock);
              break;
            case 6:
              EpidemicWarningDTO epidemicWarningDTO = queryEpidemicWarningById(t.getId());
              t.setEpidemicWarning(epidemicWarningDTO);
              break;
            default:
              break;
          }
        }
      });
    }
    return warningPage;
  }

  @Override
  public RestMessage handleWarning(Warning warning) {
    RestMessage restMsg = RestBuilders.successBuilder().build();
    warning.setHandleTime(new Date());
    warning.setModifyTime(new Date());
    warning.setHandleUser(linkappUserContextProducer.getCurrent().getId().toString());
    //warningMapper.handleWarning(warning);
    //20220908手机端处理调用新增的处理方法
    //1用户预警，2班组预警、3年龄、4证书
    Integer warningType = warning.getWarningType();
    Integer operateType = warning.getOperateType();
    Assert.isTrue(warningType != null, "预警类型为空");
    Assert.isTrue(operateType != null, "操作类型为空");
    switch (warningType) {
      case 1:
        //操作类型operateType:1退场，2忽略
        UserWarningVo userWarningVo = new UserWarningVo();
        userWarningVo.setIds(warning.getId());
        userWarningVo.setOperateType(operateType);
        userWarningVo.setHandleRemark(warning.getHandleRemark());
        restMsg = userWarningBatchOperate(userWarningVo);
        break;
      case 2:
        //操作类型operateType:1已读，2保留
        GroupWarningVo groupWarningVo = new GroupWarningVo();
        groupWarningVo.setIds(warning.getId());
        groupWarningVo.setOperateType(operateType);
        groupWarningVo.setHandleRemark(warning.getHandleRemark());
        restMsg = groupWarningBatchOperate(groupWarningVo);
        break;
      case 3:
        //操作类型operateType:1退场，2忽略
        AgeWarningVo ageWarningVo = new AgeWarningVo();
        ageWarningVo.setIds(warning.getId());
        ageWarningVo.setOperateType(operateType);
        ageWarningVo.setHandleRemark(warning.getHandleRemark());
        restMsg = ageWarningBatchOperate(ageWarningVo);
        break;
      case 4:
        //操作类型operateType:1上传、2忽略
        CertificateWarningVo certificateWarningVo = new CertificateWarningVo();
        certificateWarningVo.setIds(warning.getId());
        certificateWarningVo.setOperateType(operateType);
        certificateWarningVo.setHandleRemark(warning.getHandleRemark());
        certificateWarningVo.setUserCertificate(warning.getUserCertificate());
        restMsg = certificateWarningBatchOperate(certificateWarningVo);
        break;
      case 5:
        //操作类型operateType:1已读，2保留
        UserOutinWarningVo userOutinWarningVo = new UserOutinWarningVo();
        userOutinWarningVo.setIds(warning.getId());
        userOutinWarningVo.setOperateType(operateType);
        userOutinWarningVo.setHandleRemark(warning.getHandleRemark());
        restMsg = userOutinWarningBatchOperate(userOutinWarningVo);
        break;
      case 6:
        EpidemicWarningVo epidemicWarningVo = new EpidemicWarningVo();
        epidemicWarningVo.setIds(warning.getId());
        epidemicWarningVo.setOperateType(operateType);
        epidemicWarningVo.setHandleRemark(warning.getHandleRemark());
        epidemicWarningBatchOperate(epidemicWarningVo);
        break;
      default:
        break;
    }

    return restMsg;
  }

  @Override
  public CountWarningDTO countWarning(WarningDTO warningDTO) {
    warningDTO.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
    warningDTO.setUserType(linkappUserContextProducer.getCurrent().getType());
    // 全部
    List<Warning> totalWarnings = warningMapper.queryList(warningDTO);
    // 未处理
    warningDTO.setStatus(0);
    List<Warning> unhandleWarnings = warningMapper.queryList(warningDTO);
    // 已处理
    warningDTO.setStatus(1);
    List<Warning> handledWarnings = warningMapper.queryList(warningDTO);
    CountWarningDTO countWarning = new CountWarningDTO();
    countWarning.setTotalCount(CollectionUtils.isEmpty(totalWarnings)?0:totalWarnings.size());
    countWarning.setUnhandleCount(CollectionUtils.isEmpty(unhandleWarnings)?0:unhandleWarnings.size());
    countWarning.setHandledCount(CollectionUtils.isEmpty(handledWarnings)?0:handledWarnings.size());
    return countWarning;
  }

  @Override
  public RestMessage userWarningBatchOperate(UserWarningVo userWarningVo) {
    LinkappUser linkappUser = linkappUserContextProducer.getNotNullCurrent();

    String ids = userWarningVo.getIds();
    Assert.isTrue(StringUtils.isNotBlank(ids), "未选择记录");
    Integer type = userWarningVo.getType();
    //Assert.isTrue(type != null, "操作模块为空");
    Integer operateType = userWarningVo.getOperateType();
    Assert.isTrue(operateType != null, "操作类型为空");

    String[] idArr = ids.split(",");
    if(ArrayUtils.isNotEmpty(idArr)){
      Date now = DateUtil.date();
      for (String id:idArr){
        UserWarning userWarning = userWarningMapper.selectById(id);
        if (userWarning != null){
          if (userWarning.getStatus().intValue() == 0){
            //去查询相关预警
            QueryWrapper<UserWarning> qwWarning = new QueryWrapper<>();
            qwWarning.eq("tenant_id_",userWarning.getTenantId());
            qwWarning.eq("user_id_",userWarning.getUserId());
            qwWarning.eq("type_",userWarning.getType());
            qwWarning.eq("status_",0);
            List<UserWarning> sameLs = userWarningMapper.selectList(qwWarning);
            //理论上会查询到选择的记录，这里还是add下
            sameLs.add(userWarning);
            if(CollectionUtil.isNotEmpty(sameLs)){
              sameLs.stream().forEach(s->{
                //未处理的才能处理
                s.setModifyTime(now);
                s.setHandleTime(now);
                s.setHandleUser(linkappUser.getId().toString());
                s.setStatus(1);
                s.setOperateType(userWarningVo.getOperateType());
                //更新处理状态
                userWarningMapper.updateById(s);
                if (operateType.intValue() == 1){
                  //项目用户
                  QueryWrapper<UserProject> qw = new QueryWrapper<>();
                  qw.eq("user_id_",s.getUserId());
                  qw.eq("tenant_id_",linkappUser.getTenantId());
                  List<UserProject> userProjectList = userProjectMapper.selectList(qw);
                  if (CollectionUtil.isNotEmpty(userProjectList)){
                    userProjectList.stream().forEach(u->{
                      int oldStatus = u.getStatus();
                      if (oldStatus == 1) {
                        //在项目,设置离开项目
                        u.setStatus(0);
                        userProjectService.updateOne(u);
                      }
                    });
                  }
                  //批量退场需要下发到闸机
                  delFromGate(s.getUserId(),s.getTenantId());
                  //new Thread(() -> delFromGate(userWarning.getUserId(),userWarning.getTenantId())).start();
                }
              });
            }
          }
        }
      }
    }

    return RestBuilders.successBuilder().build();
  }

  @Override
  public RestMessage ageWarningBatchOperate(AgeWarningVo ageWarningVo) {
    LinkappUser linkappUser = linkappUserContextProducer.getNotNullCurrent();
    //操作与人员预警批量操作一致

    String ids = ageWarningVo.getIds();
    Assert.isTrue(StringUtils.isNotBlank(ids), "未选择记录");

    Integer operateType = ageWarningVo.getOperateType();
    Assert.isTrue(operateType != null, "操作类型为空");

    String[] idArr = ids.split(",");
    if (ArrayUtils.isNotEmpty(idArr)) {
      Date now = DateUtil.date();
      for (String id : idArr) {
        AgeWarning ageWarning = ageWarningMapper.selectById(id);
        if (ageWarning != null) {
          if (ageWarning.getStatus().intValue() == 0) {
            //去查询相关预警
            QueryWrapper<AgeWarning> qwWarning = new QueryWrapper<>();
            qwWarning.eq("tenant_id_", ageWarning.getTenantId());
            qwWarning.eq("user_id_", ageWarning.getUserId());
            qwWarning.eq("status_", 0);
            List<AgeWarning> sameLs = ageWarningMapper.selectList(qwWarning);
            //理论上会查询到选择的记录，这里还是add下
            sameLs.add(ageWarning);
            if (CollectionUtil.isNotEmpty(sameLs)) {
              sameLs.stream().forEach(s -> {
                //未处理的才能处理
                s.setModifyTime(now);
                s.setHandleTime(now);
                s.setHandleUser(linkappUser.getId().toString());
                s.setStatus(1);
                s.setOperateType(ageWarningVo.getOperateType());
                //更新处理状态
                ageWarningMapper.updateById(s);
                if (operateType.intValue() == 1) {
                  //项目用户
                  QueryWrapper<UserProject> qw = new QueryWrapper<>();
                  qw.eq("user_id_", s.getUserId());
                  qw.eq("tenant_id_", linkappUser.getTenantId());
                  List<UserProject> userProjectList = userProjectMapper.selectList(qw);
                  if (CollectionUtil.isNotEmpty(userProjectList)) {
                    userProjectList.stream().forEach(u -> {
                      int oldStatus = u.getStatus();
                      if (oldStatus == 1) {
                        //在项目,设置离开项目
                        u.setStatus(0);
                        userProjectService.updateOne(u);
                      }
                    });
                  }
                  //批量退场需要下发到闸机
                  delFromGate(s.getUserId(), s.getTenantId());
                  //new Thread(() -> delFromGate(userWarning.getUserId(),userWarning.getTenantId())).start();
                }
              });
            }
          }
        }
      }
    }

    return RestBuilders.successBuilder().build();
  }

  @Override
  public RestMessage certificateWarningBatchOperate(CertificateWarningVo certificateWarningVo) {
    LinkappUser linkappUser = linkappUserContextProducer.getNotNullCurrent();

    String ids = certificateWarningVo.getIds();
    Assert.isTrue(StringUtils.isNotBlank(ids), "未选择记录");

    Integer operateType = certificateWarningVo.getOperateType();
    Assert.isTrue(operateType != null, "操作类型为空");

    String[] idArr = ids.split(",");
    if (ArrayUtils.isNotEmpty(idArr)) {
      Date now = DateUtil.date();
      for (String id : idArr) {
        CertificateWarning certificateWarning = certificateWarningMapper.selectById(id);
        if (certificateWarning != null) {
          if (certificateWarning.getStatus().intValue() == 0) {
            //去查询相关预警
            QueryWrapper<CertificateWarning> qwWarning = new QueryWrapper<>();
            qwWarning.eq("tenant_id_", certificateWarning.getTenantId());
            qwWarning.eq("user_id_", certificateWarning.getUserId());
            //qwWarning.eq("type_", certificateWarning.getType());
            //qwWarning.eq("level_", certificateWarning.getLevel());
            //20220914变更：处理以证书id为准，因为原先同类型同等级证书可以挂多个
            qwWarning.eq("certificate_id_", certificateWarning.getCertificateId());
            qwWarning.eq("status_", 0);
            List<CertificateWarning> sameLs = certificateWarningMapper.selectList(qwWarning);
            //理论上会查询到选择的记录，这里还是add下
            sameLs.add(certificateWarning);
            if (CollectionUtil.isNotEmpty(sameLs)) {
              sameLs.stream().forEach(s -> {
                //未处理的才能处理
                s.setModifyTime(now);
                s.setHandleTime(now);
                s.setHandleUser(linkappUser.getId().toString());
                s.setStatus(1);
                s.setOperateType(certificateWarningVo.getOperateType());
                //更新处理状态
                certificateWarningMapper.updateById(s);

              });
            }
          }
        }
      }
    }

    return RestBuilders.successBuilder().build();
  }

  @Override
  public RestMessage getWarningCertificateInfo(String id) {
    Assert.isTrue(StringUtils.isNotBlank(id),"ID为空");
    CertificateWarning certificateWarning = certificateWarningMapper.selectById(id);
    Assert.notNull(certificateWarning,"数据不存在");

    String certificateId = certificateWarning.getCertificateId();
    if (StringUtils.isNotBlank(certificateId)){
      UserCertificate userCertificate = userCertificateMapper.selectById(certificateId);
      return RestBuilders.successBuilder().data(userCertificate).build();
    }
    return RestBuilders.successBuilder().build();
  }

  @Override
  public RestMessage certificateWarningUploadCert(CertificateWarningVo certificateWarningVo) {
    LinkappUser linkappUser = linkappUserContextProducer.getNotNullCurrent();

    String id = certificateWarningVo.getId();
    Assert.isTrue(StringUtils.isNotBlank(id), "ID为空");

    Integer operateType = certificateWarningVo.getOperateType();
    Assert.isTrue(operateType != null, "操作类型为空");

    UserCertificate userCertificate = certificateWarningVo.getUserCertificate();
    Assert.isTrue(userCertificate != null ,"证书信息为空");

    Date now = DateUtil.date();
    CertificateWarning certificateWarning = certificateWarningMapper.selectById(id);
    if (certificateWarning != null) {
      if (certificateWarning.getStatus().intValue() == 0) {
        //更新对应的人的证书信息
        userCertificate.setModifyId(linkappUser.getId());
        userCertificate.setModifyTime(now);
        userCertificate.setId(certificateWarning.getCertificateId());
        if(userCertificate.getValidTime() != null){
          userCertificate.setValidTime(DateUtil.beginOfDay(userCertificate.getValidTime()));
        }
        if(userCertificate.getStopTime() != null){
          userCertificate.setStopTime(DateUtil.beginOfDay(userCertificate.getStopTime()));
        }
        userCertificateMapper.updateById(userCertificate);

        //去查询相关预警
        QueryWrapper<CertificateWarning> qwWarning = new QueryWrapper<>();
        qwWarning.eq("tenant_id_", certificateWarning.getTenantId());
        qwWarning.eq("user_id_", certificateWarning.getUserId());
        qwWarning.eq("type_", certificateWarning.getType());
        qwWarning.eq("level_", certificateWarning.getLevel());
        qwWarning.eq("status_", 0);
        List<CertificateWarning> sameLs = certificateWarningMapper.selectList(qwWarning);
        //理论上会查询到选择的记录，这里还是add下
        sameLs.add(certificateWarning);
        if (CollectionUtil.isNotEmpty(sameLs)) {
          sameLs.stream().forEach(s -> {
            //未处理的才能处理
            s.setModifyTime(now);
            s.setHandleTime(now);
            s.setHandleUser(linkappUser.getId().toString());
            s.setStatus(1);
            s.setOperateType(certificateWarningVo.getOperateType());
            //更新处理状态
            certificateWarningMapper.updateById(s);

          });
        }
      }
    }

    return RestBuilders.successBuilder().build();
  }

  @Override
  public RestMessage groupWarningBatchOperate(GroupWarningVo groupWarningVo) {
    LinkappUser linkappUser = linkappUserContextProducer.getNotNullCurrent();

    String ids = groupWarningVo.getIds();
    Assert.isTrue(StringUtils.isNotBlank(ids), "未选择记录");

    Integer operateType = groupWarningVo.getOperateType();
    Assert.isTrue(operateType != null, "操作类型为空");

    String[] idArr = ids.split(",");
    if (ArrayUtils.isNotEmpty(idArr)) {
      Date now = DateUtil.date();
      for (String id : idArr) {
        GroupWarning groupWarning = groupWarningMapper.selectById(id);
        if (groupWarning != null) {
          if (groupWarning.getStatus().intValue() == 0) {
            //未处理的才能处理
            groupWarning.setModifyTime(now);
            groupWarning.setHandleTime(now);
            groupWarning.setHandleUser(linkappUser.getId().toString());
            groupWarning.setStatus(1);
            groupWarning.setOperateType(groupWarningVo.getOperateType());
            //更新处理状态
            groupWarningMapper.updateById(groupWarning);

            /* 暂时先不耦合处理该班组其他日期的预警
            //去查询相关预警
            QueryWrapper<GroupWarning> qwWarning = new QueryWrapper<>();
            qwWarning.eq("tenant_id_", groupWarning.getTenantId());
            qwWarning.eq("group_id_", groupWarning.getGroupId());
            qwWarning.eq("status_", 0);
            List<GroupWarning> sameLs = groupWarningMapper.selectList(qwWarning);
            //理论上会查询到选择的记录，这里还是add下
            sameLs.add(groupWarning);
            if (CollectionUtil.isNotEmpty(sameLs)) {
              sameLs.stream().forEach(s -> {
                //未处理的才能处理
                s.setModifyTime(now);
                s.setHandleTime(now);
                s.setHandleUser(linkappUser.getId().toString());
                s.setStatus(1);
                //更新处理状态
                groupWarningMapper.updateById(s);

              });
            }
            */
          }
        }
      }
    }

    return RestBuilders.successBuilder().build();
  }

  @Override
  public RestMessage epidemicWarningBatchOperate(EpidemicWarningVo epidemicWarningVo) {
    LinkappUser linkappUser = linkappUserContextProducer.getNotNullCurrent();

    String ids = epidemicWarningVo.getIds();
    Assert.isTrue(StringUtils.isNotBlank(ids), "未选择记录");

    Integer operateType = epidemicWarningVo.getOperateType();
    Assert.isTrue(operateType != null, "操作类型为空");

    String[] idArr = ids.split(",");
    if (ArrayUtils.isNotEmpty(idArr)) {
      Date now = DateUtil.date();
      for (String id : idArr) {
        EpidemicWarning epidemicWarning = epidemicWarningMapper.selectById(id);
        if (epidemicWarning != null) {
          if (epidemicWarning.getStatus().intValue() == 0) {
            //未处理的才能处理
            epidemicWarning.setModifyTime(now);
            epidemicWarning.setHandleTime(now);
            epidemicWarning.setHandleUser(linkappUser.getId().toString());
            epidemicWarning.setStatus(1);
            epidemicWarning.setOperateType(epidemicWarningVo.getOperateType());
            //更新处理状态
            epidemicWarningMapper.updateById(epidemicWarning);

          }
        }
      }
    }

    return RestBuilders.successBuilder().build();
  }

  @Override
  public RestMessage warningBatchOperate(WarningVo warningVo) {
    LinkappUser linkappUser = linkappUserContextProducer.getNotNullCurrent();
    Integer batchType = warningVo.getBatchType();
    Integer warningType = warningVo.getWarningType();

    Assert.isTrue(batchType != null, "批量操作类型不能为空");
    Assert.isTrue(warningType != null, "批量操作类型不能为空");

    //0非全部（ids）1全部，2自己
    if (batchType.intValue() == 0) {
      String ids = warningVo.getIds();
      Assert.isTrue(StringUtils.isNotBlank(ids), "未选择数据");
    }
    if (batchType.intValue() == 2) {
      warningVo.setUserId(linkappUser.getId().toString());
    }

    //预警类型 1人员出勤预警 2班组预警 3年龄预警 4证书预警 5人员出场异常
    //先只弄班组的，其他留入口
    Page page = new Page();
    page.setCurrent(1);
    page.setSize(-1);
    RequestModel<WarningDTO> warningRequestModel = new RequestModel<>();
    warningRequestModel.setPage(page);
    WarningDTO warningDTO = new WarningDTO();
    BeanUtil.copyProperties(warningVo, warningDTO, CopyOptions.create().setIgnoreNullValue(true));

    List<Integer> warningTypes = new ArrayList<>();
    warningTypes.add(warningType);
    warningDTO.setWarningTypes(warningTypes);
    warningRequestModel.setCustomQueryParams(warningDTO);
    IPage<Warning> iPage = queryWarning(warningRequestModel);

    //处理
    if (iPage != null && CollectionUtil.isNotEmpty(iPage.getRecords())) {
      Warning warning = new Warning();
      warning.setWarningType(warningVo.getWarningType());
      warning.setOperateType(warningVo.getOperateType());
      warning.setHandleRemark(warningVo.getHandleRemark());
      StringJoiner sj = new StringJoiner(",");
      List<Warning> ls = iPage.getRecords();
      if(CollectionUtil.isNotEmpty(ls)){
        ls.stream().forEach(c -> {
          sj.add(c.getId());
        });
        warning.setId(sj.toString());
        return handleWarning(warning);
      }
    }

    return RestBuilders.successBuilder().build();
  }

  @Override
  public IPage<UserOutinWarningDTO> queryUserOutinWarning(RequestModel<UserOutinWarningDTO> requestModel) {
    Page page = requestModel.getPage();
    UserOutinWarningDTO userOutinWarningDTO = requestModel.getCustomQueryParams();
    //项目id 过滤
    userOutinWarningDTO.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
    Page page1 = new Page();
    page1.setSize(100000);
    LaborCompanyProjectDTO laborCompanyProjectDTO = new LaborCompanyProjectDTO();
    laborCompanyProjectDTO.setTenantId(userOutinWarningDTO.getTenantId());
    IPage<LaborCompanyProjectDTO> laborCompanyProjectDTOIPage = laborCompanyProjectMapper
            .queryListByPage(page1, laborCompanyProjectDTO);
    //结束时间
    if (null != userOutinWarningDTO.getEndTime()) {
      userOutinWarningDTO.setEndTime(DateUtil.endOfDay(userOutinWarningDTO.getEndTime()));
    }
    IPage<UserOutinWarningDTO> userOutinWarningDTOIPage = userOutinWarningMapper.queryList(page,userOutinWarningDTO);
    userOutinWarningDTOIPage.getRecords().forEach(r -> {
      //设置参建单位
      List<LaborCompanyProjectDTO> dtos = laborCompanyProjectDTOIPage.getRecords().stream()
              .filter(re -> Objects.equals(r.getCompanyProjectId(), re.getCompanyProjectId()))
              .collect(Collectors.toList());
      if (dtos.size() > 0) {
        r.setCompanyName(dtos.get(0).getName());
      }
    });
    return userOutinWarningDTOIPage;
  }

  @Override
  public RestMessage userOutinWarningBatchOperate(UserOutinWarningVo userOutinWarningVo) {
    LinkappUser linkappUser = linkappUserContextProducer.getNotNullCurrent();

    String ids = userOutinWarningVo.getIds();
    Assert.isTrue(StringUtils.isNotBlank(ids), "未选择记录");

    Integer operateType = userOutinWarningVo.getOperateType();
    Assert.isTrue(operateType != null, "操作类型为空");

    String[] idArr = ids.split(",");
    if (ArrayUtils.isNotEmpty(idArr)) {
      Date now = DateUtil.date();
      for (String id : idArr) {
        UserOutinWarning userOutinWarning = userOutinWarningMapper.selectById(id);
        if (userOutinWarning != null) {
          if (userOutinWarning.getStatus().intValue() == 0) {
            //未处理的才能处理
            userOutinWarning.setModifyTime(now);
            userOutinWarning.setHandleTime(now);
            userOutinWarning.setHandleUser(linkappUser.getId().toString());
            userOutinWarning.setStatus(1);
            userOutinWarning.setOperateType(userOutinWarning.getOperateType());
            //更新处理状态
            userOutinWarningMapper.updateById(userOutinWarning);
          }
        }
      }
    }

    return RestBuilders.successBuilder().build();
  }

  /**
   * 从闸机删除用户
   *
   * @param userId   用户id
   * @param tenantId 租户id
   */
  private void delFromGate(String userId, String tenantId) {
    EmpUserBase empUserBase = empUserBaseMapper.selectById(userId);
    QueryWrapper<Gate> queryWrapper = new QueryWrapper();
    queryWrapper.eq("tenant_id_", tenantId)
            .isNotNull("code_");
    List<Gate> gates = gateMapper.selectList(queryWrapper);
    Set<String> codeSet = gates.stream().map(g -> g.getCode()).collect(Collectors.toSet());
    if (null != codeSet && codeSet.size() > 0) {
      //查询在不在设备库里
      QueryWrapper<Device> deviceQueryWrapper = new QueryWrapper();
      deviceQueryWrapper.in("code", codeSet);
      List<Device> devices = deviceMapper.selectList(deviceQueryWrapper);
      Set<String> codes = devices.stream().map(g -> g.getCode()).collect(Collectors.toSet());
      if (CollectionUtil.isNotEmpty(codes)) {
        codes.forEach(code -> {
          //从闸机删除，调用,不管结果，开线程处理，因为不用知道结果
          //userProjectService.delGate(empUserBase, code);
          new Thread(() -> userProjectService.delGate(empUserBase, code,false)).start();
        });
      }
    }
  }

  @Override
  public EpidemicWarningDTO queryEpidemicWarningById(String id) {
    EpidemicWarningDTO req = new EpidemicWarningDTO();
    req.setId(id);
    List<EpidemicWarningDTO> records = epidemicWarningMapper.queryList(req);
    if (CollectionUtil.isNotEmpty(records)) {
      EpidemicWarningDTO res = records.get(0);
      //设置参建单位
      LaborCompanyProject laborCompanyProject = laborCompanyProjectMapper
          .selectById(res.getCompanyProjectId());
      if (null != laborCompanyProject) {
        res.setCompanyName(laborCompanyProject.getCompanyName());
      }
      return res;
    }
    return null;
  }
}
